package com.wn.common.exception;

import com.wn.common.result.Result;
import com.wn.common.result.enums.impl.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Map;
import java.util.stream.Collectors;

/**
 *
 *   你项目中的全局异常 如何处理 ?
 *
 *   1、遇到异常 都是自定义 异常 在 出现异常进行 抛出
 *
 *   2、有全局异常处理类   @RestControllerAdvice 来声明 全局异常处理类
 *       通过  @ExceptionHandler(BusinessException.class)  来 捕获指定的异常
 *
 *  3、我们的异常 编码的设计
 *       结果异常码
 *               DATA_IS_WRONG(50002, "数据有误"),
 *               DATA_ALREADY_EXISTED(50003, "数据已存在"),
 *       业务异常码
 *              用户错误：   20001-29999
 *              贷款异常码   50001-59999
 */
@Slf4j
@RestControllerAdvice
public class GlobalException {

    // 处理业务异常
    @ExceptionHandler(BusinessException.class)
    public Result handlerBusinessException(BusinessException e) {
        e.printStackTrace();
        log.info("handlerBusinessException 的信息是:{}",e.getMessage());

        //判断 code 为null 的操作
        if (e.getErrorCode() == null){
            return Result.fail(500,e.getMessage());
        }
        return Result.fail(e.getErrorCode().getCode(),e.getErrorCode().getMessage());
    }

    // 非法参数异常
    @ExceptionHandler(IllegalArgumentException.class)
    public Result handlerException(IllegalArgumentException e) {
        e.printStackTrace();
        return Result.fail(ResultCode.PARAM_IS_INVALID);
    }

    // 参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handlerArgumentNotValidException(MethodArgumentNotValidException e) {
        e.printStackTrace();
        Map<String, String> map = e.getBindingResult().getFieldErrors().stream()
                .collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
        return Result.fail(ResultCode.PARAM_IS_BLANK,map);
    }

    // 当其他错误类型都不匹配的时候执行
    @ExceptionHandler(Exception.class)
    public Result handlerException(Exception e) {
        e.printStackTrace();
        return Result.fail(e.getMessage());
    }
}
